package org.folio.rest.impl.other.take;

import cn.hutool.core.util.StrUtil;
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;

import io.vertx.core.Handler;
import org.folio.rest.impl.other.blacklist.BlacklistService;
import org.folio.rest.impl.other.delayjob.partyattend.AttendDelayThreadInit;
import org.folio.rest.impl.other.delayjob.partyattend.PartyAttendHandler;
import org.folio.rest.impl.other.delayjob.partydelay.DelayThreadHeader;
import org.folio.rest.impl.other.delayjob.partydelay.PartyEndHandler;
import org.folio.rest.impl.other.reserve_station.ReserveEndPond;
import org.folio.rest.impl.other.reserve_station.ReserveStation;
import org.folio.rest.impl.pojo.WebPartyViews;
import org.folio.rest.jaxrs.model.Attend;
import org.folio.rest.jaxrs.model.Party;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

public class TenantsTaskService {
    private static ConcurrentHashMap<String, Boolean> tenantsMap =
            new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, ConcurrentHashMap<String,TakeInterface>> tenantsRun =
            new ConcurrentHashMap<>();
    private static Boolean getTenantsMap(String key) {
        return tenantsMap.get (key);
    }

    private static void setTenantsMap(String key, Boolean value) {
        TenantsTaskService.tenantsMap.put(key, value);
    }

    public static ConcurrentHashMap<String, ConcurrentHashMap<String, TakeInterface>> getTenantsRun() {
        return tenantsRun;
    }

    public static void startTake(Context vertxContext, Map<String, String> okapiHeaders){
        String tenant = okapiHeaders.get("x-okapi-tenant");
        if (!StrUtil.isBlankOrUndefined(tenant) &&  TenantsTaskService.getTenantsMap(tenant)==null ){
            ConcurrentHashMap<String,TakeInterface> record = new ConcurrentHashMap<>();
            PartyEndHandler partyEndHandler = DelayThreadHeader.initThread(vertxContext.owner(),tenant);
            //PartyEndHandler partyEndHandler = new PartyEndHandler(vertxContext.owner(),tenant);
            PartyAttendHandler  partyAttendHandler=AttendDelayThreadInit.initThread(vertxContext.owner(),tenant);
            //PartyAttendHandler  partyAttendHandler=new PartyAttendHandler(vertxContext.owner(),tenant);

            ReserveStation reserveStation = new ReserveStation(vertxContext.owner(),tenant);
            WebPartyViews webPartyViews=new WebPartyViews(vertxContext.owner(),tenant);

            BlacklistService blacklistService= new BlacklistService(vertxContext.owner(),tenant);
            record.put("webPartyViews",webPartyViews);
            record.put("blacklistService",blacklistService);
            record.put("reserveStation",reserveStation);
            record.put("partyEndHandler",partyEndHandler);
            record.put("partyAttendHandler",partyAttendHandler);
            tenantsRun.put(tenant,record);
            TenantsTaskService.setTenantsMap(tenant,true);
        }

    }

    public static void timeTake( ){
        tenantsRun.forEach((a,b)->{
            b.forEach((c,d)->{
                d.timeTake();
            });
        });
    }
    public static void timeTakeBySwitchRule( ){
        tenantsRun.forEach((a,b)->{
            b.forEach((c,d)->{
                d.switchRules();
            });
        });
    }
    public static Optional<TakeInterface> getService(String tenant, String serviceName){
        ConcurrentHashMap<String, TakeInterface> service = tenantsRun.get(tenant);
        if (service ==null){
            return Optional.empty();
        }else{
            return Optional.of(service.get(serviceName));
        }
      }

    public static void setJob(String tenant, String serviceName, Party party ){
        if (StrUtil.isBlankOrUndefined(tenant) || StrUtil.isBlankOrUndefined(serviceName) ){
            return  ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get(serviceName);
             if (funcObject !=null){
                 funcObject.setJob(party);
             }
        }
        return ;
    }
    public static void removeAndFreed(String tenant, String serviceName, Party party ){
        if (StrUtil.isBlankOrUndefined(tenant) || StrUtil.isBlankOrUndefined(serviceName) ){
            return  ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get(serviceName);
            if (funcObject !=null){
                funcObject.removeAndFreed(party);
            }
        }
        return ;
    }
    public static void updateJob(String tenant, String serviceName, Party party ){
        if (StrUtil.isBlankOrUndefined(tenant) || StrUtil.isBlankOrUndefined(serviceName) ){
            return  ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get(serviceName);
            if (funcObject !=null){
                funcObject.updateJob(party);
            }
        }
        return ;
    }

    public static void delJob(String tenant, String serviceName, Party party ){
        if (StrUtil.isBlankOrUndefined(tenant) || StrUtil.isBlankOrUndefined(serviceName) ){
            return  ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get(serviceName);
            if (funcObject !=null){
                funcObject.delJob(party);
            }
        }
        return ;
    }



    public static void updatePartyAttendJob(String tenant, String serviceName, Party party ){
        if (StrUtil.isBlankOrUndefined(tenant) || StrUtil.isBlankOrUndefined(serviceName) ){
            return  ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get(serviceName);
            if (funcObject !=null){
                funcObject.updatePartyAttendJob(party);
            }
        }
        return ;
    }
    public static void setJob(String tenant, String serviceName,Attend attend){
        if (StrUtil.isBlankOrUndefined(tenant) || StrUtil.isBlankOrUndefined(serviceName) ){
            return  ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get(serviceName);
            if (funcObject !=null){
                funcObject.setJob(attend);
            }
        }
        return ;
    }

    public static void setIntCounter(String tenant,String partyId, Handler<AsyncResult<Integer>> asyncResultHandler){
        if (StrUtil.isBlankOrUndefined(tenant)   ){
            return  ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get("webPartyViews");
            if (funcObject !=null){
                funcObject.setIntCounter(partyId,asyncResultHandler);
            }
        }
        return ;
    }
    //

    public static Integer getIntCounter(String tenant,String partyId ){
        if (StrUtil.isBlankOrUndefined(tenant)   ){
            return 0 ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get("webPartyViews");
            if (funcObject !=null){
               return funcObject.getIntCounter(partyId );
            }
        }
        return 0;
    }

    public static Optional<ReserveEndPond> getReserveEndPond(String tenant ){
        if (StrUtil.isBlankOrUndefined(tenant)   ){
            return null ;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get("reserveStation");
            if (funcObject !=null){
                return Optional.of(funcObject.getReserveEndPond());
            }
        }
        return Optional.empty();
    }
    public static Party getReserveStationParty (String tenant,String partyId  ){
        if (StrUtil.isBlankOrUndefined(tenant)   ){
            return null;
        }
        ConcurrentHashMap<String, TakeInterface> value = tenantsRun.get(tenant);
        if (value !=null){
            TakeInterface funcObject = value.get("reserveStation");
            if (funcObject !=null){
                return funcObject.getPartyById(partyId);
            }
        }
        return null;
    }
}
